package org.fing.edu.uy.esbadp.core;

import java.io.Serializable;
import java.util.Date;

import org.fing.edu.uy.esbadp.core.entity.GenericTreeNode;

/*
 * Implementa la lista de acciones requeria para realizar la adaptacion.
 * Esta lista contendra las distintas acciones como RUT,RET,TRN,SRV1. 
 */
public class AdpFlowTree implements Serializable {
	
	private static final long serialVersionUID = 957466274776130173L;
	private GenericTreeNode<AdpFlowInterface> flowTree;
	private GenericTreeNode<AdpFlowInterface> current;	
	private long serviceID;
	private Date expiredDate;
	//indica si esta adaptacion es la generica, ( llamada directa al servicio y por ende no expira)
	private boolean defaultADP = false;
	private int nextNodeIndex;
	private boolean saveHistoric;
	
	public AdpFlowTree(){
		this.setFlowTree(new GenericTreeNode<AdpFlowInterface>());
		nextNodeIndex = 0;
		saveHistoric = false;
	}	
	
	public AdpFlowTree(AdpFlowTree adpTree){
		this.setFlowTree(adpTree.flowTree);		
		this.setCurrent(adpTree.current);
		this.expiredDate = adpTree.getExpiredDate();
		this.defaultADP = adpTree.isDefaultADP();
		nextNodeIndex = adpTree.getNextNodeIndex();
		this.saveHistoric =  adpTree.isSaveHistoric();
		this.serviceID = adpTree.serviceID;
	}
	
	public AdpFlowTree(long serviceID, GenericTreeNode<AdpFlowInterface> flowTree){
		this.setFlowTree(flowTree);
		this.setCurrent(flowTree);
		this.nextNodeIndex = 0;
		this.serviceID =  serviceID;
	}
	
	public Date getExpiredDate() {
		return expiredDate;
	}

	public void setExpiredDate(Date expiredDate) {
		this.expiredDate = expiredDate;
	}

	public GenericTreeNode<AdpFlowInterface> getFlowTree() {
		return flowTree;
	}

	public void setFlowTree(GenericTreeNode<AdpFlowInterface> flowTree) {
		this.flowTree = flowTree;
	}
	
	public GenericTreeNode<AdpFlowInterface> getCurrent() {	
		return current;
	}
	
	public boolean isNullFlowTree() {
		return flowTree == null || flowTree.getData() == null;
	}
	
	public void setCurrent(GenericTreeNode<AdpFlowInterface> current) {
		if(this.current!=null){
			this.current.setIndex(nextNodeIndex);
			nextNodeIndex++;
		}
		this.current = current;
		
	}
				
	public boolean isDefaultADP() {
		return defaultADP;
	}

	public void setDefaultADP(boolean defaultADP) {
		this.defaultADP = defaultADP;
	}
		
	
	public int getNextNodeIndex() {
		return nextNodeIndex;
	}

	public void setNextNodeIndex(int nextNodeIndex) {
		this.nextNodeIndex = nextNodeIndex;
	}

	/**
	 * 
	 * @return true en caso de que la adaptacion este activa ( es la por defecto o no expiro aun )
	 * 		   false en caso de que la adaptacion este expirada
	 */
	public boolean isActiveADP(){
		if(this.defaultADP){
			return true;
		}
		Date now = new Date();
		if(this.expiredDate.before(now)){
			return false;
		}else{
			return true;
		}		
	}
	
	public boolean isSaveHistoric() {
		return saveHistoric;
	}

	public void setSaveHistoric(boolean saveHistoric) {
		this.saveHistoric = saveHistoric;
	}

		
	public long getServiceID() {
		return serviceID;
	}

	public void setServiceID(long serviceID) {
		this.serviceID = serviceID;
	}

	@Override
	public Object clone(){
		AdpFlowTree clone = new AdpFlowTree(serviceID,flowTree.clone());
		clone.setExpiredDate(expiredDate);
		clone.setSaveHistoric(saveHistoric);
	    clone.setDefaultADP(defaultADP);
		clone.setNextNodeIndex(nextNodeIndex);
		clone.setServiceID(serviceID);
		return clone;
	}
		
	/*public Object cloneAndReset(){
		
	}*/
	
	@Override
	public String toString(){
		StringBuilder builder = new StringBuilder("Expired Date: ");
		if(this.defaultADP){
			builder.append("Never is defaultADP").append("\n");
		}else{
			builder.append(this.expiredDate).append("\n");
		}
		
		builder.append("ServiceID:");
		builder.append(this.serviceID).append("\n");
		builder.append("Next index:");
		builder.append(this.nextNodeIndex).append("\n");
		
		builder.append(this.flowTree.toString());
		return builder.toString();
	}
	
}
